package me.midday.java.base.knowledge.loadclass;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class CompileClassLoader extends ClassLoader{

    private byte[] getBytes(String filename) throws IOException {
        File file = new File(filename);
        long len = file.length();
        byte[] raw = new byte[(int)len];

        FileInputStream fin = new FileInputStream(file);
        int r = fin.read(raw);
        if (r!=len){
            throw new IOException("无法读取全部文件：" + r + "!=" + len);
        }
        return raw;
    }

    private boolean compile(String javaFile) throws IOException, InterruptedException {
        System.out.println("CompileClassLoader : 正在编译 " + javaFile + "... ");
        Process p = Runtime.getRuntime().exec("javac" + javaFile);
        p.waitFor();
        int ret = p.exitValue();
        return ret == 0;
    }

    @Override
    protected Class<?> findClass(String name){
        Class clazz = null;
        String fileStub = name.replace(".","/");
        String javaFilename = fileStub + ".java";
        String classFilename = fileStub + ".class";
        File javaFile = new File(javaFilename);
        File classFile  = new File(classFilename);
        if(javaFile.exists()&& (!classFile.exists())|| javaFile.lastModified() > classFile.lastModified()){
            try {
                if(!compile(javaFilename)|| !classFile.exists()){
                    throw new ClassNotFoundException("ClassNotFoundException:" + javaFilename);

                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        if (classFile.exists()){
            try {
                byte[] raw = getBytes(classFilename);
                clazz = defineClass(name, raw, 0, raw.length);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return clazz;
    }


    public static void main(String[] args){

    }


}
